/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.debugger.support.util; import java.util.HashSet; import java.util.Iterator; /** A task that may be executed in a separate thread and permits examination of its status. * Other threads can check if it is finished or wait for it * to finish. * <P> * For example: * <p><code><PRE> * Runnable r = new Runnable () { * public void run () { * // do something * } * }; * Task task = new Task (r); * RequestProcessor.postRequest (task); * </PRE></code> * <p>In a different thread one can then test <CODE>task.isFinished ()</CODE> * or wait for it with <CODE>task.waitFinished ()</CODE>. * * @author Jaroslav Tulach */ class Task extends Object implements Runnable { /** Dummy task which is already finished. */ public static final Task EMPTY = new Task(null); /** what to run */ private Runnable run; /** flag if we have finished */ private boolean finished; /** Create a new task. * The runnable should provide its own error-handling, as * by default thrown exceptions are simply logged and not rethrown. * @param run runnable to run that computes the task */ public Task(Runnable run) { this.run = run; if (run == null) { finished = true; } } /** Test whether the task has finished running. * @return <code>true</code> if so */ public final boolean isFinished () { return finished; } /** Wait until the task is finished. */ public final void waitFinished () { waitFinishedImpl(); } /** This method is an implementation of the waitFinished method * This implemetation run the task and then returns. */ void waitFinishedImpl () { if (!finished) { synchronized (this) { while (!finished) { try { wait (); } catch (InterruptedException ex) { } } } } } /** Notify all waiters that this task has finished. * @see #run */ protected final void notifyFinished () { Iterator it; synchronized (this) { finished = true; notifyAll (); } } /** Start the task. * When it finishes (even with an exception) it calls * {@link #notifyFinished}. * Subclasses may override this method, but they * then need to call {@link #notifyFinished} explicitly. * <p>Note that this call runs synchronously, but typically the creator * of the task will call this method in a separate thread. */ public void run () { try { finished = false; if (run != null) run.run (); } catch (Throwable t) { if (t instanceof ThreadDeath) { throw (ThreadDeath)t; } if (System.getProperty ("netbeans.debug.exceptions") != null) { System.out.println("Exception occurred in request processor:"); t.printStackTrace (); } } finally { notifyFinished (); } } public String toString () { return "task " + run; } } /* * Log * 1 Jaga 1.0 3/27/00 Daniel Prusa * $ */